package com.stenio.fancat.service.baby;

import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stenio.fancat.domain.baby.BabyAccount;
import com.stenio.fancat.domain.baby.BabyIconImage;
import com.stenio.fancat.domain.baby.BabyPartner;
import com.stenio.fancat.domain.baby.BabyRelationship;
import com.stenio.fancat.domain.bo.UserRelationshipBO;
import com.stenio.fancat.domain.user.UserRelationship;
import com.stenio.fancat.domain.user.UserRelationshipCandy;
import com.stenio.fancat.domain.user.UserRelationshipName;
import com.stenio.fancat.exception.FanCatException;
import com.stenio.fancat.form.baby.BabyAccountForm;
import com.stenio.fancat.form.user.UserRelationshipForm;
import com.stenio.fancat.mapper.baby.BabyAccountMapper;
import com.stenio.fancat.mapper.baby.BabyIconImageMapper;
import com.stenio.fancat.mapper.baby.BabyPartnerMapper;
import com.stenio.fancat.mapper.baby.BabyRelationshipMapper;
import com.stenio.fancat.mapper.user.*;
import com.stenio.fancat.util.EmptyUtil;
import com.stenio.fancat.util.RedisUtil;
import com.stenio.fancat.util.StringUtil;
import com.stenio.fancat.vo.BabyAccountVO;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * baby基本信息类
 */
@Service
public class BabyAccountService extends ServiceImpl<BabyAccountMapper, BabyAccount> {

    @Autowired
    private BabyAccountMapper babyMapper;

    @Autowired
    private BabyIconImageMapper babyIconImageMapper;

    @Autowired
    private UserRelationshipMapper userRelationshipMapper;

    @Autowired
    private BabyRelationshipMapper babyRelationshipMapper;

    @Autowired
    private UserRelationshipNameMapper userRelationshipNameMapper;

    @Autowired
    private UserRelationshipCandyMapper userRelationshipCandyMapper;

    @Autowired
    private UserRelationshipLogMapper userRelationshipLogMapper;

    @Autowired
    private BabyPartnerMapper babyPartnerMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Value("${key}")
    private String key;
    @Value("${listKey}")
    private String listKey;

    /**
     * 增加baby的基本信息
     * @param babyAccountForm
     * @return
     */
    @Transactional
    public BabyAccountVO insertBabyAccountByCondition(BabyAccountForm babyAccountForm,UserRelationshipForm userRelationshipForm){
        if(null == babyAccountForm && null == userRelationshipForm){
            throw new RuntimeException("参数不能为空");
        }
        //判断user是否注册过baby
        UserRelationship user = userRelationshipMapper.selectUserInfoById(userRelationshipForm.getUserId());
        System.out.println(user);
        if(user.getBabyId() !=  null && user.getBabyId().length() != 0){
            throw new RuntimeException("您已经注册过宝宝，不能重复注册");
        }

        BabyAccountVO babyAccountVO = new BabyAccountVO();
        BabyAccount babyAccount = new BabyAccount();
        Date date = new Date();
        babyAccount.setBabyId(StringUtil.getUUID());
        babyAccount.setBirthday(babyAccountForm.getBirthday());
        babyAccount.setGender(babyAccountForm.getGender());  //性别,1男,2女
        babyAccount.setNickName(babyAccountForm.getNickName());
        babyAccount.setSurplusCandy(0);  //新增baby，初始化金额
        babyAccount.setTotalCandy(0);    //新增baby，初始化金额
        babyAccount.setUpdateTime(date);
        babyAccount.setCreateTime(date);

        int number = babyMapper.insert(babyAccount);
        BabyAccount baby = null;
        if(number > 0){
            baby = babyMapper.selectById(babyAccount);
            UserRelationship userRelationship = new UserRelationship();  //用户
            userRelationship.setUserId(userRelationshipForm.getUserId());
            userRelationship.setBabyId(baby.getBabyId());
            userRelationship.setRelationship(userRelationshipForm.getRelationship());//设置baby关系
            userRelationshipMapper.updateBabyIdById(userRelationship);  //更新baby关系表信息

            BabyRelationship babyRelationship = new BabyRelationship();
            babyRelationship.setBabyId(baby.getBabyId());
            babyRelationship.setUserId(userRelationshipForm.getUserId());
            babyRelationship.setCreateTime(date);
            babyRelationship.setUpdateTime(date);
            babyRelationshipMapper.insert(babyRelationship);  //插入baby关系表

            //新用户注册，小程序⽤户首次授权并创建宝宝信息，+500糖果币  先修改babyAccount的账户SurplusCandy，TotalCandy
            babyMapper.modifyCandy(500,baby.getBabyId());
            //在修改当前user——candy的账户信息
            userRelationshipCandyMapper.modifyCandy(500,userRelationshipForm.getUserId());
            //在修改当前user——log的账户信息,先查询当前baby的账户金额，然后修改相应的信息
            //当前不需查询baby的金额是因为刚创建的用户默认账户里面是0；
            userRelationshipLogMapper.modifyCandy(500,userRelationshipForm.getUserId(),0);
        }

        try {
            BeanUtils.copyProperties(babyAccountVO,baby);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return babyAccountVO;
    }

    /**
     * 查询宝宝的基本信息
     * @param userRelationshipForm
     * @return
     */
    public BabyAccountVO selectBabyAccountByCondition(UserRelationshipForm userRelationshipForm) throws FanCatException {
        if(null == userRelationshipForm){
            throw new FanCatException("参数不能为空");
        }

        //判断Redis中是否含有key
        BabyRelationship babyRelationship = babyRelationshipMapper.selectBabyByUid(userRelationshipForm.getUserId());
        if(EmptyUtil.isEmpty(babyRelationship)){
            throw new FanCatException("该用户下没有宝宝信息，请添加");
        }
        String babyId = babyRelationship.getBabyId();
        if(null != redisUtil.get(key+babyId)){
            return (BabyAccountVO) redisUtil.get(key+babyId);
        }

        BabyAccountVO babyAccountVO = new BabyAccountVO();

        UserRelationship userRelationship = new UserRelationship();
        try {
            BeanUtils.copyProperties(userRelationship,userRelationshipForm);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        UserRelationship u = userRelationshipMapper.selectOne(userRelationship);
        String name = userRelationshipNameMapper.selectName(u.getRelationship()).getRelationshipName();
        babyAccountVO.setRelationshipName(name);
        if(EmptyUtil.isEmpty(u.getBabyId())){
            throw new FanCatException("该用户下没有宝宝信息，请添加");
        }
        BabyAccount babyAccount = new BabyAccount();
        babyAccount.setBabyId(u.getBabyId());
        BabyAccount baby = babyMapper.selectOne(babyAccount);
        babyAccountVO.setBirthday(baby.getBirthday());
        babyAccountVO.setGender(baby.getGender());
        babyAccountVO.setNickName(baby.getNickName());
        babyAccountVO.setRank(this.babyRank(u.getBabyId()));
        babyAccountVO.setSurplusCandy(baby.getSurplusCandy());
        babyAccountVO.setTotalCandy(baby.getTotalCandy());

        // 通过用户ID查询(baby's icon)
        BabyIconImage entity = new BabyIconImage();
        entity.setBabyId(u.getBabyId());
        babyAccountVO.setImage(babyIconImageMapper.selectOne(entity).getImage());

        //存放Redis中
        redisUtil.set(key+babyId,babyAccountVO);

        return babyAccountVO;
    }


    /**
     * 修改宝宝基本信息
     * @param userRelationshipForm
     * @return
     */
    @Transactional
    public BabyAccount modifyBabyAccountByCondition(UserRelationshipForm userRelationshipForm,BabyAccountForm babyAccountForm) throws FanCatException {
        if(null == userRelationshipForm){
            throw new RuntimeException("参数不能为空");
        }

        BabyRelationship babyRelationship = babyRelationshipMapper.selectBabyByUid(userRelationshipForm.getUserId());

        BabyAccount babyAccount = new BabyAccount();
        babyAccount.setBabyId(babyRelationship.getBabyId());
        babyAccount.setTotalCandy(babyAccountForm.getTotalCandy());
        babyAccount.setNickName(babyAccountForm.getNickName());
        babyAccount.setGender(babyAccountForm.getGender());
        babyAccount.setBirthday(babyAccountForm.getBirthday());
        babyAccount.setSurplusCandy(babyAccountForm.getSurplusCandy());
        babyAccount.setUpdateTime(new Date());

        babyMapper.modifyBabyInfo(babyAccount);

        //操作Redis
        String babyId = babyRelationship.getBabyId();
        redisUtil.del(key+babyId);

        return babyMapper.selectByBid(babyAccount.getBabyId());
    }


    /**
     * 根据userId查询亲人列表(我的个人信息页面)
     * @param userRelationshipForm
     * @return
     */
    public List<UserRelationshipBO> selectUserListByBabyId(UserRelationshipForm userRelationshipForm) throws FanCatException {
        if(null == userRelationshipForm){
            throw new FanCatException("参数异常");
        }

        UserRelationship user = userRelationshipMapper.selectUserInfoById(userRelationshipForm.getUserId());
        //查询亲人列表
        List<UserRelationship> listBaby = userRelationshipMapper.selectRelationship(user.getBabyId());
        List<UserRelationshipBO> listUser = new ArrayList<>();
        for(int i=0; i < listBaby.size(); i++){
            if (listBaby.get(i).getRelationship()==1 || listBaby.get(i).getRelationship()==2) {
                //user Info
                UserRelationshipBO userRelationshipBO = new UserRelationshipBO();
                UserRelationship userRelationship = userRelationshipMapper.selectUserInfoById(listBaby.get(i).getUserId());
                if(listBaby.get(i).getUserId().equals(userRelationshipForm.getUserId()) ){
                    userRelationship.setName("我");
                }
                //user relationName
                UserRelationshipName userRelationshipName = new UserRelationshipName();
                userRelationshipName.setRelationship(userRelationship.getRelationship());
                UserRelationshipName u = userRelationshipNameMapper.selectOne(userRelationshipName);

                //user candy
                UserRelationshipCandy userRelationshipCandy = new UserRelationshipCandy();
                userRelationshipCandy.setUserId(userRelationship.getUserId());
                UserRelationshipCandy ursc = userRelationshipCandyMapper.selectOne(userRelationshipCandy);

                //user image;
                UserRelationship userSec = userRelationshipMapper.selectUserInfoById(userRelationship.getUserId());

                userRelationshipBO.setBabyId(userRelationship.getBabyId());
                userRelationshipBO.setName(userRelationship.getName());
                userRelationshipBO.setUserId(userRelationship.getUserId());
                userRelationshipBO.setIncreaseCandy(ursc.getIncreaseCandy());
                userRelationshipBO.setRelationshipName(u.getRelationshipName());
                userRelationshipBO.setImage(userSec.getIcon());
                listUser.add(userRelationshipBO);
            }
        }

        return listUser;
    }

    /**
     * 计算宝宝在伙伴圈的排名
     * @param babyId
     * @return
     */
    public Integer babyRank(String babyId) throws FanCatException {
        if(null == babyId){
            throw new FanCatException("参数异常");
        }
        Integer rank = 1;
        List<BabyPartner> partnersList = babyPartnerMapper.selectBabyPartnerByBid(babyId);
        if(partnersList.isEmpty()){
           rank = 0;
           return rank;
        }

        //查询该baby的总金额
        BabyAccount baby = babyMapper.selectByBid(babyId);
        Integer candys = baby.getTotalCandy();

        for(int i = 0;i < partnersList.size();i++){
            BabyAccount babyAccount = babyMapper.selectByBid(partnersList.get(i).getAssociatedBabyId());
            Integer money = babyAccount.getTotalCandy();
            if(candys < money){
                rank++;
            }
        }

        return rank;
    }

}
